#include "camera.h"
#include <windows.h>

matrix44 camera_t::getViewMatrix() const
{
	if (m_bFreeMode)
		return RotateRadMatrix44('x', -m_fTheta) * RotateRadMatrix44('y', m_fPhi) * RotateRadMatrix44('x', DegToRad(-90.0f)) * TranslateMatrix44(-m_Pos.x, -m_Pos.y, -m_Pos.z);
	else
		return TranslateMatrix44(0.0, 0.0, -m_fDistance) * RotateRadMatrix44('y', -m_fPhi) * RotateRadMatrix44('x', m_fTheta);
}

matrix44 camera_t::getProjectionMatrix() const
{
	return PerspectiveMatrix44(m_fViewAngle, m_fW/m_fH, m_fNear, m_fFar);
}

vector3 camera_t::getPosition() const
{
	matrix44 mView = getViewMatrix();
	mView.invert();
	return vector3(mView * vector4(0.0f, 0.0f, 0.0f, 1.0f));
}

void camera_t::setProjection( float viewAngle, float w, float h, float fnear, float ffar )
{
	m_fViewAngle = viewAngle;
	m_fW = w;
	m_fH = h;
	m_fFar = ffar;
	m_fNear = fnear;
}

void camera_t::mouseProc( int uMsg, int x, int y )
{
	static bool bWasLeftButtonDown = false, bWasRightButtonDown = false;
	static int  oldx = 0, oldy = 0;

	if( bWasLeftButtonDown )
	{
		float a = DegToRad(180.0f)/300.0f;
		m_fPhi += (float)(x-oldx)*a;
		m_fTheta += (float)(oldy-y)*a;
	}
	else
	if( bWasRightButtonDown )
	{
		float a = 0.1f;
		m_fDistance -= (float)(oldy-y)*a;
		if (m_fDistance < 0.01f)
			m_fDistance = 0.01f;
		if (m_fDistance > 100.0f)
			m_fDistance = 100.0f;
	}

	oldx = x;
	oldy = y;
	if( uMsg == LBUTTONDOWN )
		bWasLeftButtonDown = true;
	if( uMsg == LBUTTONUP )
		bWasLeftButtonDown = false;
	if( uMsg == RBUTTONDOWN )
		bWasRightButtonDown = true;
	if( uMsg == RBUTTONUP )
		bWasRightButtonDown = false;
}

void camera_t::kbdProc(int pressed)
{
	static int		wasPressed = 0;
	static DWORD	timeLast = GetTickCount();

	DWORD time = GetTickCount();

	if (m_bFreeMode)
	{
	float	 speed = 2.5f;

	matrix44 mView = getViewMatrix();

	float dt = (float)(time-timeLast)/1000.0f;
	if (pressed & 0x01)		// forward
	{
		if (wasPressed & 0x01)
		{
			vector3 d(mView.col[0][2], mView.col[1][2], mView.col[2][2]);
			m_Pos -= (speed * dt) * d;
		}
	}
	else if (pressed & 0x02)	// back
	{
		if (wasPressed & 0x02)
		{
			vector3 d(mView.col[0][2], mView.col[1][2], mView.col[2][2]);
			m_Pos += (speed * dt) * d;
		}
	}
	else if (pressed & 0x04)	// right
	{
		if (wasPressed & 0x04)
		{
			vector3 d(mView.col[0][0], mView.col[1][0], mView.col[2][0]);
			m_Pos += (speed * dt) * d;
		}
	}
	else if (pressed & 0x08)	// left
	{
		if (wasPressed & 0x08)
		{
			vector3 d(mView.col[0][0], mView.col[1][0], mView.col[2][0]);
			m_Pos -= (speed * dt) * d;
		}
	}
	else if (pressed & 0x10)	// up
	{
		if (wasPressed & 0x10)
		{
			vector3 d(mView.col[0][1], mView.col[1][1], mView.col[2][1]);
			m_Pos += (speed * dt) * d;
		}
	}
	else if (pressed & 0x20)	// down
	{
		if (wasPressed & 0x20)
		{
			vector3 d(mView.col[0][1], mView.col[1][1], mView.col[2][1]);
			m_Pos -= (speed * dt) * d;
		}
	}

	}
	timeLast = time;
	wasPressed = pressed;
}

